#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>

#include "domain.h"

#define REQUEST_NUMBER 20
#define PROCESS_NUMBER 3

void send_requests() {
	
	int result[1024];	
	char argument[1024];
	key_t handle[1024];

	struct timeval start_time;
	struct timeval end_time;
	struct timeval run_time;

	int i;

	// blocking requests
	// gettimeofday(&start_time, NULL);

	// blocking_request(argument, &(result[0]));
	// blocking_request(argument, &(result[1]));
	
	// gettimeofday(&end_time, NULL);
	// timersub(&end_time, &start_time, &run_time);

	// printf("[Client %d] Finished all synchronous requests in %ds %dms\n", getpid(), run_time.tv_sec, run_time.tv_usec / 1000);
	
	// unblocking requests
	gettimeofday(&start_time, NULL);

	for ( i = 0; i < REQUEST_NUMBER; i++ ) {
		handle[i] = unblocking_request(argument, &(result[i]));
	}

	for ( i = 0; i < REQUEST_NUMBER; i++ ) {
		result[i] = wait_for_results(handle[i]);
	}

	gettimeofday(&end_time, NULL);
	timersub(&end_time, &start_time, &run_time);

	printf("[Client %d] Finished all asynchronous requests in %ds %dms\n", getpid(), run_time.tv_sec, run_time.tv_usec / 1000);
}

void main(int argc, char** argv){

	pid_t pid[1024], service_pid;
	int i, status, index;

	printf("\n**********************\n");

	domain_init();

	// -------- start service --------

	service_pid = fork();

	if (service_pid < 0) {
		fprintf(stderr, "service process create fail in main\n");
		return;
	}

	if (service_pid == 0) {
		start_service();
		return;
	}

	sleep(1);

	// -------- start clients --------

	for(i=0; i<1024; i++)
		pid[i] = -9999;
	
	for(i=0; i<PROCESS_NUMBER; i++){
		pid[i] = fork();
		if(pid[i] == -1){
			fprintf(stderr, "client process create fail in main\n");
		}
		if(pid[0] == 0){
			connect_service(1);
			send_requests();
			disconnect_service();
			return;
		}
		if(pid[1] == 0){
			connect_service(2);
			send_requests();
			disconnect_service();
			return;
		}
		if(pid[2] == 0){
			connect_service(5);
			send_requests();
			disconnect_service();
			return;
		}
	}
	
	for (i=0; i<PROCESS_NUMBER; i++) {
		waitpid(pid[i], &status, 0);
	}
	sleep(2);
	// -------- stop service --------
	stop_service(service_pid);

	if (domain_finalize() == -1) {
		fprintf(stderr, "domain finalize fail in main\n");
	}

	printf("**********************\n");
//	sleep(5);	
//	message_get_all();

}
